// pid 父级id type 1 一级菜单  2 二级菜单 3权限按钮
const treeData = [
	{
		id: 1,
		name: '首页',
		pid: 0,
		type: 1,
		children: [],
	},
	{
		id: 2,
		name: '系统权限',
		pid: 0,
		type: 1,
		children: [
			{
				id: 3,
				name: '角色管理',
				pid: 2,
				type: 2,
				children: [
					{
						id: 6,
						name: '添加角色',
						pid: 3,
						type: 3,
					},
					{
						id: 7,
						name: '修改角色',
						pid: 3,
						type: 3,
					},
					{
						id: 8,
						name: '删除角色',
						pid: 3,
						type: 3,
					},
					{
						id: 9,
						name: '配置权限',
						pid: 3,
						type: 3,
					},
				],
			},
			{
				id: 4,
				name: '用户管理',
				pid: 2,
				type: 2,
				children: [],
			},
			{
				id: 5,
				name: '权限管理',
				pid: 2,
				type: 2,
			},
		],
	},
]

const flatData = [
	{ id: 1, name: '首页', pid: 0, type: 1 },
	{ id: 2, name: '系统权限', pid: 0, type: 1 },
	{ id: 3, name: '角色管理', pid: 2, type: 2 },
	{ id: 6, name: '添加角色', pid: 3, type: 3 },
	{ id: 7, name: '修改角色', pid: 3, type: 3 },
	{ id: 8, name: '删除角色', pid: 3, type: 3 },
	{ id: 9, name: '配置权限', pid: 3, type: 3 },
	{ id: 4, name: '用户管理', pid: 2, type: 2 },
	{ id: 5, name: '权限管理', pid: 2, type: 2 },
]

/**
 * 打平树形结构 的 常规写法
 * @param {*} treeData 树形结构数据
 * @returns 打平后的数据
 */
function flatTree(treeData = []) {
	const res = []
	function _(treeData) {
		for (const item of treeData) {
			const { children, ...i } = item
			res.push(i)
			if (children && children.length) {
				_(children)
			}
		}
	}
	_(treeData)
	return res
}

function flatTree2(treeData = []) {
	let res = []
	treeData.forEach((item) => {
		const { children, ...i } = item
		res.push(i)
		if (children && children.length) {
			res = res.concat(flatTree(children))
		}
	})
	return res
}

function flatTree3(treeData = []) {
	return treeData.reduce((p, c) => {
		const { children, ...i } = c
		return p.concat(i, children && children.length ? flatTree2(children) : [])
	}, [])
}
// console.log(flatTree(treeData))

/**
 * 构建树形结构的常规写法
 * @param {*} flatData 树形结构数据
 * @returns 树形结构数组
 */
function markTree(flatData = []) {
	const res = []
	const map = {}
	for (const item of flatData) {
		// 构造 关系 [{1:{首页} }，....]
		// 利用 pid === id /  map[item.pid]  找到自己的父亲
		map[item.id] = item
		if (item.pid === 0) {
			res.push(item)
		} else {
			// 找到父级
			// 把自己添加到父级的children 数组中
			// 1. 父级 已经存在 children  2. 或者父级没有children
			const parentArr = map[item.pid]
			parentArr.children = parentArr.children || []
			parentArr.children.push(item)
		}
	}

	return res
}

function markTree2(flatData = []) {
	const res = []
	function _(res, pid) {
		for (const item of flatData) {
			if (item.pid == pid) {
				const newItem = { ...item, children: [] }
				res.push(newItem)
				_(newItem.children, newItem.id)
			}
		}
	}
	_(res, 0)
	return res
}
// console.log(markTree2(flatData))

/**
 * 查询某子个节点的 父节点信息
 * 常用 修改按钮权限
 */

function findParentNode(treeData = [], curNode) {
	let res = null
	function _(treeData, curNode) {
		treeData.forEach((item) => {
			const { children } = item
			if (children && children.length) {
				_(children, curNode)
			}
			if (item.id === curNode.pid) {
				res = item
			}
		})
	}
	_(treeData, curNode)
	return res
}
// console.log(findParentNode(treeData, { pid: 3 }))

/**
 * 保留非按钮的节点 常用于渲染左侧菜单
 * 去除所有 type ==3 的节点
 */

function getMenus(treeData = []) {
	let res = JSON.parse(JSON.stringify(treeData))

	function _(treeData) {
		treeData.forEach((item) => {
			if (item.type === 3) {
				// 找到父元素 并删除
				let parentNode = findParentNode(res, item)
				parentNode && parentNode.children && (parentNode.children = [])
			}
			const { children } = item
			if (children && children.length) {
				_(children)
			}
		})
	}
	_(res)
	return res
}

// console.log(getMenus(treeData))

/**
 * 获取当前节点的所有子节点
 *
 */
function getChildNode(treeData = [], curNode) {
	let res = null
	function _(treeData, curNode) {
		for (const item of treeData) {
			if (item.id === curNode.id) {
				res = item?.children
			}
			const { children } = item
			if (children && children.length) {
				_(children, curNode)
			}
		}
	}
	_(treeData, curNode)
	return res
}

// console.log(getChildNode(treeData, { id: 2 }))

/**
 * 为所有的节点插入属性 checked :false
 *
 */

function insertAttr(treeData = [], attrObj) {
	let backups = JSON.parse(JSON.stringify(treeData))
	return backups.map((item) => {
		const hasChildren = item.children && item.children.length
		return {
			...item,
			...attrObj,
			children: hasChildren ? insertAttr(item.children, attrObj) : [],
		}
	})
}

// console.log(insertAttr(treeData, { checked: false }))

/**
 * 修改所有节点的键值, name 改为 title
 */

function changeAttrs(treeData = [], attrObj) {
	let backups = JSON.parse(JSON.stringify(treeData))
	return backups.map((item) => {
		const hasChildren = item.children && item.children.length
		const newItem = {}
		Object.keys(attrObj).forEach((key) => {
			newItem[attrObj[key]] = item[key]
		})
		newItem.children = hasChildren ? changeAttrs(item.children, attrObj) : []
		return newItem
	})
}
// console.log(changeAttrs(treeData, { name: 'title' }))

/**
 * 查询某个节点信息
 */
function findNode(treeData = [], currentNode) {
	let res = null
	function _(treeData, currentNode) {
		treeData.forEach((item) => {
			if (item.name == currentNode.name) {
				res = item
			}
			const { children } = item
			if (children && children.length) {
				_(children, currentNode)
			}
		})
	}
	_(treeData, currentNode)
	return res
}

// console.log(findNode(treeData, { id: 9, name: '配置权限', pid: 3, type: 3 }))

/**
 * 构造一个符合element ui Tree的树形结构数据
 */
let testData = {
	首页: [
		{
			kpi_name: '首页-category2-1',
			content: '0001',
			category: 'category2',
		},
		{
			kpi_name: '首页-category1-1',
			content: '0001',
			category: 'category1',
		},
		{
			kpi_name: '首页-category1-2',
			content: '0001',
			category: 'category1',
		},
		{
			kpi_name: '首页-category3-1',
			content: '0001',
			category: 'category3',
		},
	],
	系統管理: [
		{
			kpi_name: '系統管理-category2-1',
			content: '0001',
			category: 'category2',
		},
		{
			kpi_name: '系統管理-category8-1',
			content: '0001',
			category: 'category8',
		},
		{
			kpi_name: '系統管理-category1-1',
			content: '0001',
			category: 'category1',
		},
		{
			kpi_name: '系統管理-category3-1',
			content: '0001',
			category: 'category3',
		},
	],
	项目配置: [
		{
			kpi_name: '项目配置-category2-1',
			content: '0001',
			category: 'category2',
		},
		{
			kpi_name: '项目配置-category1-1',
			content: '0001',
			category: 'category1',
		},
		{
			kpi_name: '项目配置-category1-2',
			content: '0001',
			category: 'category1',
		},
		{
			kpi_name: '项目配置-category3-1',
			content: '0001',
			category: 'category3',
		},
	],
}

function foo(testData) {
	// 构造父级格式
	let treeNode = []
	Object.keys(testData).forEach((item) => {
		treeNode.push({ label: item })
	})
	// 构造节点
	for (const key in testData) {
		if (Object.hasOwnProperty.call(testData, key)) {
			const element = testData[key]
			element.label = element.kpi_name
			let item = treeNode.find((item) => item.label === key)
			item.children = item.children || []
			let res = tools(element)
			for (const key in res) {
				const element = res[key]
				item.children.push(element)
			}
		}
	}
	console.log(treeNode)
	return treeNode
}
function tools(arr) {
	let obj = {}
	// 构造二级和三级节点
	arr.forEach((el) => {
		let temp = obj[el.category]
		el.label = el.kpi_name
		if (!temp) {
			obj[el.category] = { label: el.category, children: [] }
			temp = obj[el.category]
		}
		temp.children.push(el)
	})

	return obj
}
foo(testData)
